package org.zuel.lkq.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zuel.lkq.domain.*;
import org.zuel.lkq.enums.QStatusEnum;
import org.zuel.lkq.enums.RoleEnum;
import org.zuel.lkq.mapper.QuestionMapper;
import org.zuel.lkq.mapper.TalkMapper;
import org.zuel.lkq.mapper.UserMapper;
import org.zuel.lkq.param.user.talk.*;
import org.zuel.lkq.service.UserTalkService;
import org.zuel.lkq.util.MySecurityUtil;
import org.zuel.lkq.util.ResponseUtil;
import org.zuel.lkq.viewmodel.user.talk.HistoryQuestionInfoVM;
import org.zuel.lkq.viewmodel.user.talk.QuestionDetailVM;
import org.zuel.lkq.viewmodel.user.talk.TalkDetailVM;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserTalkServiceImpl implements UserTalkService {

    public final QuestionMapper questionMapper;

    public final UserMapper userMapper;

    public final TalkMapper talkMapper;

    @Autowired
    public UserTalkServiceImpl(QuestionMapper questionMapper,
                               UserMapper userMapper,
                               TalkMapper talkMapper) {

        this.questionMapper = questionMapper;
        this.userMapper = userMapper;
        this.talkMapper = talkMapper;
    }

    @Override
    public Object createQuestion(CreateQuestionParam param) {
        if (param == null) {
            return ResponseUtil.badArgument();
        }
        Question question = new Question();
        BeanUtils.copyProperties(param, question);
        question.setPdId(MySecurityUtil.getCurrentUserId());
        question.setAddTime(LocalDateTime.now());
        questionMapper.insertSelective(question);

        Talk talk = new Talk();
        talk.setQuestionId(question.getId());
        talk.setContent(question.getDetail());
        talk.setUserId(MySecurityUtil.getCurrentUserId());
        talk.setTalkType(RoleEnum.SUBSCRIBER.getType());
        talk.setAddTime(LocalDateTime.now());
        talkMapper.insertSelective(talk);

        return ResponseUtil.ok(question);
    }

    @Override
    public Object queryAllQuestion(QueryQuestionParam param) {
        if (param == null) {
            return ResponseUtil.badArgument();
        }

        QuestionExample example = new QuestionExample();
        example.setOrderByClause("add_time desc");
        QuestionExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andPdIdEqualTo(MySecurityUtil.getCurrentUserId());
        if (param.getTitle() != null) {
            criteria.andTitleLike("%" + param.getTitle() + "%");
        }
        if (param.getStatus() != null) {
            criteria.andQStatusEqualTo(param.getStatus());
        }
        List<Question> questions = questionMapper.selectByExample(example);

        List<HistoryQuestionInfoVM> vmList = questions.stream().map(q -> {
            HistoryQuestionInfoVM vm = new HistoryQuestionInfoVM();
            BeanUtils.copyProperties(q, vm);
            vm.setPdPerson(MySecurityUtil.getCurrentUsername());
            vm.setAnswerPerson(getAnswerPerson(q.getAnswerId()));
            return vm;
        }).collect(Collectors.toList());
        return ResponseUtil.ok(vmList);
    }

    @Override
    public Object questionDetail(TalkDetailParam param) {
        if (param == null) {
            return ResponseUtil.badArgument();
        }
        QuestionExample example = new QuestionExample();
        QuestionExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andIdEqualTo(param.getId());
        Question question = questionMapper.selectOneByExampleWithBLOBs(example);
        QuestionDetailVM vm = new QuestionDetailVM();
        BeanUtils.copyProperties(question, vm);
        vm.setAnswerPerson(getAnswerPerson(question.getAnswerId()));
        return vm;
    }

    private String getAnswerPerson(Integer id) {
        if (id == null) {
            return "暂无";
        }
        User user = userMapper.selectByPrimaryKey(id);
        return user.getUsername();
    }

    @Override
    public Object talkDetail(TalkDetailParam param) {
        if (param == null) {
            return ResponseUtil.badArgument();
        }

        TalkExample example = new TalkExample();
        TalkExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andQuestionIdEqualTo(param.getId());
        List<Talk> talkList = talkMapper.selectByExampleWithBLOBs(example);

        Map<Integer, String> userMap = new HashMap<>();
        for (Talk talk : talkList) {
            if (userMap.size() == 2) {
                break;
            }
            if (!userMap.containsKey(talk.getUserId())) {
                User user = userMapper.selectByPrimaryKey(talk.getUserId());
                userMap.put(talk.getUserId(), user.getUsername());
            }
        }

        List<TalkDetailVM> vmList = talkList.stream().map(t -> {
            TalkDetailVM vm = new TalkDetailVM();
            BeanUtils.copyProperties(t, vm);
            vm.setPerson(userMap.get(vm.getUserId()));
            String wipeLabel = t.getContent()
                    .replace("<p>", "")
                    .replace("</p>","");
            vm.setContent(wipeLabel);
            return vm;
        }).collect(Collectors.toList());
        return ResponseUtil.ok(vmList);
    }

    @Override
    public Object createTalkDetail(TalkCreateParam param) {
        if (param == null) {
            return ResponseUtil.badArgument();
        }
        Talk talk = new Talk();
        BeanUtils.copyProperties(param, talk);
        int userId = MySecurityUtil.getCurrentUserId();
        talk.setUserId(userId);
        talk.setTalkType(RoleEnum.SUBSCRIBER.getType());
        talk.setAddTime(LocalDateTime.now());
        talkMapper.insertSelective(talk);
        return ResponseUtil.ok(talk);
    }

    @Override
    public Object terminateQuestion(TerminateQuestionParam param) {
        if (param == null) {
            return ResponseUtil.badArgument();
        }
        Question q = new Question();
        q.setqStatus(QStatusEnum.TERMINATED.getStatus());
        q.setId(param.getId());
        questionMapper.updateByPrimaryKeySelective(q);
        return ResponseUtil.ok("工单已终结！");
    }

}
